class_name ControllerCommandManager

#region 属性
var controller_component:ControllerComponent
var controller_command_dict:Dictionary = {} # {command_type:{tag:[]}
var next_command_id:int = 0
var inited:bool = false
var enable:bool = false
#endregion
#region 字段
#endregion
#region 信号
#endregion

#region 基类方法
#endregion
#region 公共方法
func init(controller_component:ControllerComponent):
	self.controller_component = controller_component
	self.inited = true
	set_enable(true)
func set_enable(enable:bool):
	self.enable = enable
func add_controller_command(tag:String,controller_command:ControllerCommand) -> int:
	controller_command = controller_command.duplicate(true)
	controller_command.id = next_command_id
	next_command_id += 1
	controller_command.activate_tick = Time.get_ticks_msec()
	var type_dict:Dictionary = controller_command_dict.get_or_add(controller_command.command_type,{}) if controller_command.command_type != GameEnum.ControllerCommandType.None else {}
	if type_dict.has(tag):
		match controller_command.command_tag_conflict_resolution:
			GameEnum.ControllerCommandTagConflictResolution.Ignore:
				return -1
			GameEnum.ControllerCommandTagConflictResolution.Separate:
				var arr:Array = type_dict.get_or_add(tag,[])
				arr.append(controller_command)
				arr.sort_custom(func(c0:ControllerCommand,c1:ControllerCommand):return c0.priority < c1.priority)
				controller_command.activate(controller_component,type_dict)
				return controller_command.id
			GameEnum.ControllerCommandTagConflictResolution.Cover:
				var arr:Array = type_dict.get_or_add(tag,[])
				type_dict.erase(tag)
				if arr.size() > 0:
					arr[0].deactivate(controller_component,type_dict)
				arr = type_dict.get_or_add(tag,[])
				arr.append(controller_command)
				arr.sort_custom(func(c0:ControllerCommand,c1:ControllerCommand):return c0.priority < c1.priority)
				controller_command.activate(controller_component,type_dict)
				return controller_command.id
			GameEnum.ControllerCommandTagConflictResolution.HighPriority:
				var arr:Array = type_dict.get_or_add(tag,[])
				if arr.size() > 0 and arr[0].priority < controller_command.priority:
					arr[0].deactivate(controller_component,type_dict)
					arr.clear()
					arr.append(controller_command)
					arr.sort_custom(func(c0:ControllerCommand,c1:ControllerCommand):return c0.priority < c1.priority)
					controller_command.activate(controller_component,type_dict)
					return controller_command.id
				else:
					return -1
			_:
				return -1
	else:
		var arr:Array = type_dict.get_or_add(tag,[])
		arr.append(controller_command)
		arr.sort_custom(func(c0:ControllerCommand,c1:ControllerCommand):return c0.priority < c1.priority)
		controller_command.activate(controller_component,type_dict)
		return controller_command.id
## 移除指定tag
func remove_controller_command_by_tag(tag:String):
	for controller_command_type in controller_command_dict.keys():
		var commands:Array = controller_command_dict[controller_command_type].get(tag,[])
		for command in commands:
			controller_command_dict[controller_command_type][tag].erase(command)
			command.deactivate(controller_component,controller_command_dict[controller_command_type])
			if controller_command_dict[controller_command_type][tag].size() == 0:
				controller_command_dict[controller_command_type].erase(tag)
			if controller_command_dict[controller_command_type].keys().size() == 0:
				controller_command_dict.erase(controller_command_type)
## 移除指定controller_command_type
func remove_controller_command_by_controller_command_type(controller_command_type:GameEnum.ControllerCommandType):
	for tag in controller_command_dict.get(controller_command_type,{}).keys():
		var commands:Array = controller_command_dict[controller_command_type].get(tag,[])
		for command in commands:
			controller_command_dict[controller_command_type][tag].erase(command)
			command.deactivate(controller_component,controller_command_dict[controller_command_type])
			if controller_command_dict[controller_command_type][tag].size() == 0:
				controller_command_dict[controller_command_type].erase(tag)
			if controller_command_dict[controller_command_type].keys().size() == 0:
				controller_command_dict.erase(controller_command_type)
## 移除指定id
func remove_controller_command_by_command_id(command_id:int):
	for controller_command_type in controller_command_dict.keys():
		for tag in controller_command_dict[controller_command_type].keys():
			var commands:Array = controller_command_dict[controller_command_type].get(tag,[])
			commands = commands.filter(func(c):return c.id == command_id)
			for command in commands:
				controller_command_dict[controller_command_type][tag].erase(command)
				command.deactivate(controller_component,controller_command_dict[controller_command_type])
				if controller_command_dict[controller_command_type][tag].size() == 0:
					controller_command_dict[controller_command_type].erase(tag)
				if controller_command_dict[controller_command_type].keys().size() == 0:
					controller_command_dict.erase(controller_command_type)
## 移除指定tag、controller_command_type、id的controller_command
func remove_controller_command(tag:String,controller_command_type:GameEnum.ControllerCommandType,command_id:int):
	if controller_command_dict.has(controller_command_type) and controller_command_dict[controller_command_type].has(tag):
		var commands:Array = controller_command_dict[controller_command_type][tag].filter(func(c):return c.id == command_id)
		for command in commands:
			controller_command_dict[controller_command_type][tag].erase(command)
			if command.is_excute_deactive_when_remove:
				command.deactivate(controller_component,controller_command_dict[controller_command_type])
			if controller_command_dict[controller_command_type][tag].size() == 0:
				controller_command_dict[controller_command_type].erase(tag)
			if controller_command_dict[controller_command_type].keys().size() == 0:
				controller_command_dict.erase(controller_command_type)
func process():
	if not inited or not enable:
		return
	for type in controller_command_dict.keys():
		for tag in controller_command_dict[type].keys():
			var commands:Array = controller_command_dict[type][tag]
			for command in commands:
				command.handle_count += 1
				if command.duration >= 0:
					if (command.activate_tick + command.duration * 1000 <= Time.get_ticks_msec()) or (command.handle_count >= command.max_handle_count):
						remove_controller_command(tag,type,command.id)
func destroy():
	self.enable = false
#endregion
#region 私有方法
#endregion
#region 生命周期函数
#endregion
